<?php

namespace App\Kuafu\Activity\Model;

use App\Kuafu\Activity\Enum\ActivityEnum;
use App\Kuafu\Base\Model\Traits\KfSoftDeletes;
use App\Kuafu\Base\Model\Traits\KfUid;
use App\Kuafu\Coupon\Model\CouponModel;
use App\Kuafu\CustomerCoupon\Enum\CustomerCouponCodeEnum;
use App\Kuafu\CustomerCoupon\Exceptions\CustomerCouponException;
use App\Kuafu\CustomerCoupon\Model\CustomerSendCouponLogModel;
use App\Kuafu\Shop\Model\Shop;
use Illuminate\Database\Eloquent\Builder;
use App\Kuafu\Base\Model\BaseModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class ActivityModel extends BaseModel
{
    use KfSoftDeletes, KfUid;

    protected $connection = 'mysql';
    protected $table      = 'activities';
    protected $primaryKey = 'id';
    protected $fillable   = [
        'name',
        'startAt',
        'endAt',
        'type',
        'status',
        'shopType',
        'limitJoinNum',
        'hasJoinNum',
        'isSmsNotify',
        'isWechatNotify',
        'notifyAheadDays',
        'pushText',
        'isAttendEd',
        'description',
        'shortLinkUrl',
        'brandId',
        'channel',
        'thresholdAmount',
        'posAutoJoin',
        'isAttendOpenActivity',
        'productType'
    ];
    protected $appends    = ['activityTime', 'activityDetailTime', "startAtText", "endAtText"];

    protected $hidden = [
        'updatedAt',
        'isDeleted'
    ];

    /**
     * 活动表和优惠券表关联关系
     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
     */
    public function coupons()
    {
        return $this->hasManyThrough(
            CouponModel::class,
            ActivityCouponMappingModel::class,
            'activityId',
            'id',
            'id',
            'couponId'
        );
    }

    /**
     * 活动表和门店表关联关系
     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
     */
    public function shops()
    {
        return $this->hasManyThrough(
            Shop::class,
            ActivityShopMappingModel::class,
            'activityId',
            'id',
            'id',
            'shopId'
        );
    }

    public function activityShopMappingRel()
    {
        return $this->hasMany(ActivityShopMappingModel::class, 'activityId', 'id');
    }

    /**
     * 活动时间文字
     * @return string  长期活动 / 2021-09-22 ~ 2021-09-25
     */
    public function getActivityTimeAttribute(): string
    {
        if (0 == $this->startAt) {
            return '长期活动';
        }
        return sprintf("%s ~ %s", date('Y-m-d', $this->startAt), date('Y-m-d', $this->endAt));
    }

    /**
     * 活动时间文字
     * @return string  长期活动 / 2021-09-22 12:00 ~ 2021-09-25 13:39
     */
    public function getActivityDetailTimeAttribute(): string
    {
        if (0 == $this->startAt) {
            return '长期活动';
        }
        return sprintf("%s ~ %s", date('Y-m-d H:i', $this->startAt), date('Y-m-d H:i', $this->endAt));
    }


    public function getStartAtTextAttribute(): string
    {
        return formatDate($this->startAt, 0);
    }

    public function getEndAtTextAttribute(): string
    {
        return formatDate($this->endAt, 0);
    }

    /**
     * 门店显示列表
     * @return string[]   ["全部门店"], ["直营"], ["加盟"] ["上海日月光", "北京簋街", ...]
     */
    public function getShopListAttribute()
    {
        $r = [ActivityEnum::SHOP_TYPES[$this->shopType] ?? ''];
        if (ActivityEnum::SHOP_TYPE_SELECTION == $this->shopType) {
            $r = $this->shops->map(function ($shop) {
                return $shop->name;
            });
        }
        return $r;
    }


    public function getShopListIdsAttribute()
    {
        $r = [];
        if (ActivityEnum::SHOP_TYPE_SELECTION == $this->shopType) {
            $r = $this->shops->map(function ($shop) {
                return $shop->id;
            });
        }
        return $r;
    }

    public function getTypeTextAttribute(): string
    {
        return ActivityEnum::TYPES[$this->type] ?? '';
    }

    public function getStatusTextAttribute(): string
    {
        return ActivityEnum::STATUS[$this->status] ?? '';
    }

    /**
     * 活动详情【未处理的活动详情数据】
     * @param $id
     * @return Builder|Model|object|null
     */
    public static function info($id)
    {
//        return self::query()
//                   ->with('activitiesCouponRel',function ($query) {
//                       $query->select(['number']);
//                   })
//                   ->with('activitiesShopRel')
//                   ->where('id','=',$id)
//                   ->first();

        return self::query()
                   ->with('activitiesCouponRel')
                   ->with('activitiesShopRel')
                   ->where('id', '=', $id)
                   ->first();

    }

    /**
     * 活动详情
     * @param $id
     * @return array
     */
    public static function activities($id)
    {
        return self::query()
                   ->with(['coupons', 'shop'])
                   ->find($id)->toArray();
    }

    public static function getDataPage(int $pageSize, int $pageNum, array $where)
    {
        return self::query()
                   ->where($where)
                   ->orderByDesc('id')
                   ->paginate($pageSize, '*', 'page', $pageNum)->toArray();
    }

    //获取活动列表所有活动id
    public static function getActivityList()
    {
        return self::query()->get();
    }


    public static function addData(array $data)
    {
        return self::query()->create($data);
    }

    public static function setData(int $id, array $data): int
    {
        $query = self::query()->where('id', $id)->first();
        if (!$query) {
            return 0;
        }

        foreach ($data as $k => $v) {
            $query->$k = $v;
        }

        return $query->save();
    }

    public static function setStatus(int $id, int $status): int
    {
        return self::query()->where('id', $id)->update(['status' => $status]);
    }

    public static function delData(int $id): int
    {
        return self::query()->where('id', $id)->update(['isDeleted' => 1]);
    }


    public function activityShopRel()
    {
        return $this->hasMany(ActivityShopMappingModel::class, 'activityId', 'id');
    }

    public function activityCouponRel()
    {
        return $this->hasMany(ActivityCouponMappingModel::class, 'activityId', 'id');
    }

    public static function getActivityListByType($activityType, $status, $field)
    {
        return ActivityModel::query()
                            ->with([
                                'activityShopRel' => function ($query) {
                                    return $query->select(['activityId', 'shopId']);
                                }
                            ])
                            ->where(['type' => $activityType, 'status' => $status])
                            ->select($field)
                            ->orderBy('createdAt', 'DESC')
                            ->get();
    }

    public static function getActivityIdsByShopId(int $shopId, int $type, $brandId)
    {
        return self::query()
                   ->where(function ($query) use ($shopId) {
                       $query->where('shopType', ActivityEnum::SHOP_TYPE_ALL)
                             ->orWhereIn("id", function ($query) use ($shopId) {
                                 $query->select("activityId")
                                       ->from((new ActivityShopMappingModel())->getTable())
                                       ->where("shopId", $shopId);
                             });
//                             ->orWhereHas('activityShopRel', function ($query) use ($shopId) {
//                                 $query->where(['shopId' => $shopId]);
//                             });
                   })
                   ->where([
                       'status'  => ActivityEnum::STATUS_RUNNING,
                       'type'    => $type,
                       'brandId' => $brandId
                   ])
                   ->select(['id', 'name'])
                   ->get();

    }

    public static function getShopRelByActivityIds($activityIds)
    {
        return self::query()
                   ->with([
                       'activityShopRel' => function ($query) {
                           return $query->select(['activityId', 'shopId']);
                       }
                   ])
                   ->whereIn('id', $activityIds)
                   ->select('id')
                   ->get();
    }

    public function couponRelByActivity()
    {
        return $this->hasManyThrough(
            CouponModel::class, ActivityCouponMappingModel::class, 'activityId', 'id', 'id', 'couponId');
    }

    public static function getCouponRelByActivityIds($activityIds)
    {
        return self::query()
                   ->with([
                       'couponRelByActivity' => function ($query) {
                           $query->groupBy('couponId');
                       }
                   ])
                   ->whereIn('id', $activityIds)
                   ->select(['id', 'shopType'])
                   ->get();
    }

    public static function getAllTypeActivityIds($type, $brandId)
    {
        return self::query()
                   ->where([
                       'shopType' => ActivityEnum::SHOP_TYPE_ALL,
                       'status'   => ActivityEnum::STATUS_RUNNING,
                       'type'     => $type,
                       'brandId'  => $brandId
                   ])
                   ->select('id')->get();
    }

    public static function getTypeActivityIds($shopType, $type, $brandId)
    {
        return self::query()
                   ->where([
                       'shopType' => $shopType,
                       'status'   => ActivityEnum::STATUS_RUNNING,
                       'type'     => $type,
                       'brandId'  => $brandId
                   ])
                   ->select('id')
                   ->get();
    }

    /**
     * @return HasMany
     */
    public function activityImageRel(): HasMany
    {
        return $this->hasMany(ActivityImageMappingModel::class, "activityId", "id");
    }

    /**
     * 校验用户是否参与过活动
     *
     * @param int $uid
     * @param int $activityId
     * @return bool
     */
    public static function checkJoinActivity(int $uid, int $activityId): bool
    {
        return (bool)CustomerSendCouponLogModel::query()
                                               ->where(['userId' => $uid, 'activityId' => $activityId])
                                               ->first();
    }

    /**
     * 校验是否参与过门店某类型的活动
     *
     * @param int $shopId
     * @param int $uid
     * @param int $activityType
     * @return bool
     */
    public static function checkJoinShopTypeActivity(int $shopId, int $uid, int $activityType): bool
    {
        return (bool)CustomerSendCouponLogModel::query()
                                               ->where("shopId", $shopId)
                                               ->where("userId", $uid)
                                               ->where("activityType", $activityType)
                                               ->first();
    }

    /**
     * 校验门店是否参与过当前活动
     *
     * @param int $activityId
     * @param int $shopId
     * @return Builder|Model|object|null
     */
    public static function checkShopActivityExists(int $activityId, int $shopId)
    {
        return ActivityModel::query()
                            ->where("id", $activityId)
                            ->where(function ($query) use ($shopId) {
                                $shopType = Shop::query()->where("id", $shopId)->first()->type;
                                $query->whereIn("shopType", [0, $shopType])
                                      ->orWhereIn("id", function ($query) use ($shopId) {
                                          $query->select("activityId")
                                                ->from((new ActivityShopMappingModel())->getTable())
                                                ->where("shopId", $shopId);
                                      });

//                                      ->orWhereHas('activityShopMappingRel',
//                                          function ($query) use ($shopId) {
//                                              $query->where('shopId', $shopId);
//                                          });
                            })->first();
    }

    /**
     * @return HasMany
     */
    public function activityProductRel(): HasMany
    {
        return $this->hasMany(ActivityProductMappingModel::class, "activityId", "id");
    }
}
